<?
// 本人不熟悉XML，可能注解对XML的描述有误
// 这只是个思想，要实现的话应该略加修整，可以把一些不常用条件查询的数据用XML保存
// 如虚拟社区的 用户资料，一般只有用户自己或其他用户指定了他的USERNAME才会显示
// 剩下每次都要开启、查询、解释数据集、关闭数据库的消耗。


define ( "enter", chr ( 13 ) . chr ( 10 ) );
class DataXML //关键！！！一个自定义类
{
	var $parser; //XML解释器
	var $tags; //XML标签
	var $on; //
	var $root; // 根元素
	var $Data = array (); // 元素数组
	

	function DataXML($filename, $root) //类初始函数 filename文件名,root根元素
{
		$this->root = $root; // 初始根元素
		$this->parser = xml_parser_create (); //创建解释对象
		xml_set_object ( &$this->parser, &$this ); //设置对象
		xml_set_element_handler ( $this->parser, "tag_on", "tag_off" ); //设置元素管理函数
		xml_set_character_data_handler ( $this->parser, "getdata" ); //设置数据管理事件
		xml_parser_set_option ( $this->parser, XML_OPTION_CASE_FOLDING, 0 ); //要求严格区分大小写
		

		if (file_exists ( $filename )) //找到文件吗？
{ //找到
			$fp = fopen ( $filename, "r" ); // 只读打开
			$c = fread ( $fp, filesize ( $filename ) ); //读取数据
			fclose ( $fp ); //关闭
			$this->parse ( $c ); //设置解释对象
		}
	}
	
	function parse($data) //解释函数
{
		xml_parse ( $this->parser, $data );
	}
	
	function tag_on($parser, $tag, $attributes) //发现元素触发函数
{
		$this->on = true; // 已经触发过
		$this->tags = $tag;
		//echo $tag;
	}
	
	function tag_off($parser, $tag) //元素结素函数
{
		$this->on = false; // 元素结素
	}
	
	function getdata($parser, $cdata) //取出元素
{
		if ($this->on && $this->tags != $this->root) { //验证一下比较好，（现在是否为元素的开始，并且不是根元素？）
			

			$this->Data [$this->tags] = trim ( $cdata );
			// 关键啊！！用标签做数组表，并给这个数组元素付上数据
		//echo trim($cdata);
		//echo $this->tags;
		//echo "\n";
		}
	}
	function check($str) { //检查字符
		if (strlen ( $str ) < 1) //如果是空字符
			return ' '; //返回 ' '
		else
			return $str; //否则原路返回（不然XML好象会不做结束标记）
	}
	function saveas($filename) //另存为
{
		$c = '<?xml version="1.0" encoding="GB2312" standalone="no"?>
' . enter;
		//这个不用说了吧，enter是define("enter",chr(13).chr(10));
		$c .= "<" . $this->root . ">" . enter;
		//首先设定一下根元素
		for(reset ( $this->Data ); $i = key ( $this->Data ); next ( $this->Data )) { //开始举出所有数据啦
			$c .= "<" . $i . ">" . $this->check ( $this->Data [$i] ) . "</" . $i . ">" . enter;
			// 用数组表名做元素标签，并加上数据内容
		}
		//echo $c;
		$c .= "</" . $this->root . ">" . enter; //结束标签
		$fp = fopen ( $filename, "w" ); //写入文件
		fwrite ( $fp, $c );
		fclose ( $fp );
	}
}
